package com.vshop.platform.system.crud.dao;

import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.vshop.platform.system.domain.entity.SysDept;
import com.vshop.platform.system.crud.mapper.SysDeptMapper;
import com.vshop.platform.system.domain.param.SysDeptParam;
import org.springframework.stereotype.Repository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

import static com.mybatisflex.core.query.QueryMethods.findInSet;
import static com.mybatisflex.core.query.QueryMethods.number;
import static com.vshop.platform.system.domain.entity.table.SysDeptTableDef.SysDeptTable;
import static com.vshop.platform.system.domain.entity.table.SysUserTableDef.SysUserTable;


/**
 * 部门表 服务层实现。
 *
 * @author vshop
 * @since 2024-11-18
 */
@RequiredArgsConstructor
@Slf4j
@Repository
public class SysDeptDao extends ServiceImpl<SysDeptMapper, SysDept> {
    public QueryWrapper buildQueryWrapper(SysDeptParam param) {
        return QueryWrapper.create()
                .from(SysDeptTable)
                .and(SysDeptTable.DeptId.eq(param.getDeptId()))
                .and(SysDeptTable.ParentId.eq(param.getParentId()))
                .and(SysDeptTable.DeptName.like(param.getDeptName()))
                .and(SysDeptTable.Status.eq(param.getStatus()))
                .orderBy(SysDeptTable.Ancestors.asc())
                .orderBy(SysDeptTable.ParentId.asc())
                .orderBy(SysDeptTable.SortNum.asc());
    }

    /**
     * 修改子元素关系
     *
     * @param deptId       被修改的部门ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
        //select * from SysDeptTable where find_in_set(#{deptId}, ancestors)
        QueryWrapper queryWrapper = QueryWrapper.create()
                .from(SysDeptTable)
                .where(findInSet(number(deptId), SysDeptTable.Ancestors).gt(0));

        List<SysDept> children = this.list(queryWrapper);
        for (SysDept child : children) {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
            this.updateChain()
                    .from(SysDeptTable)
                    .set(SysDeptTable.Ancestors, child.getAncestors())
                    .where(SysDeptTable.DeptId.eq(child.getDeptId()))
                    .update();
        }
    }

    /**
     * 是否存在正常状态的子节点
     *
     * @param deptId 部门ID
     * @return 子部门数
     */
    public boolean hasNormalChildByDeptId(Long deptId) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(QueryMethods.count(SysDeptTable.DeptId))
                .from(SysDeptTable)
                .where(SysDeptTable.Status.eq("0"))
                .and(findInSet(number(deptId), SysDeptTable.Ancestors).gt(0));
//        return this.getObjAs(queryWrapper, Long.class);
        return this.count(queryWrapper) > 0;
    }


    /**
     * 是否存在子节点
     *
     * @param deptId 部门ID
     * @return 结果
     */
    public boolean hasChildByDeptId(Long deptId) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(QueryMethods.count(SysDeptTable.DeptId))
                .from(SysDeptTable)
                .and(SysDeptTable.ParentId.eq(deptId));
        return this.count(queryWrapper) > 0;
    }

    /**
     * 校验部门名称是否唯一(同级)
     *
     * @param param 部门信息
     * @return 结果
     */
    public boolean checkExistDeptName(SysDeptParam param) {
        long deptId = ObjectUtil.isNull(param.getDeptId()) ? -1L : param.getDeptId();
        QueryWrapper queryWrapper = QueryWrapper.create();
        queryWrapper.from(SysDeptTable)
                .where(SysDeptTable.DeptName.eq(param.getDeptName()))
                .and(SysDeptTable.ParentId.eq(param.getParentId()))
                .and(SysDeptTable.DeptId.ne(deptId));
        return this.exists(queryWrapper);
    }

    /**
     * 检验部门是否存在用户
     *
     * @param deptId 部门ID
     * @return 结果 true 存在 false 不存在
     */
    public boolean checkDeptHasUserByDeptId(Long deptId) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(QueryMethods.count(SysUserTable.UserId))
                .from(SysUserTable)
                .where(SysUserTable.DeptId.eq(deptId))
                .and(SysUserTable.DeleteFlag.eq(0));
        return this.count(queryWrapper) > 0;
    }

}
